package com.spring.framework.config.async.annotation;

import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author xuweizhi
 */
@Component
public class AsyncMethod {

	/**
	 * 加入@Lazy注解，再添加一层代理，这里将注入代理对象的代理对象
	 */
	@Lazy
	@Resource
	private AsyncMethod asyncMethod;

	@Async("taskExecutor")
	public void log() {
		System.out.println("-----log：" + Thread.currentThread().getName());
	}

	@Async("threadPoolTaskExecutor1")
	public void log2() {
		System.out.println("-----log2：" + Thread.currentThread().getName());
		//期望通过引入的代理对象调用log3()方法，这样就能保证同一个类中的AOP增强生效
		asyncMethod.log3();
	}

	/**
	 * 经过多次测试，我们会发现log3()方法虽然标注了@Async注解，但是异步执行没有生效，因为该方法被log2()调用，
	 * 而这两个方法都在同一个组件类中，这是由于代理的局限性导致的。
	 * <p>
	 * 启动，发现直接报错，这就是前面说的异常
	 * <p>
	 * 解决办法前面也给了，那就是加一个@Lazy注解，再添加一层代理，这里将注入代理对象的代理对象
	 * <p>
	 * 再次测试，发现每个方法都是用不同的线程，通过@Lazy注解可以比较优雅的解决了@Async方法互相调用不生效的问题，
	 * 这种方法也可以解决@Async方法的普通AOP增强的同样问题。
	 */
	@Async("threadPoolTaskExecutor2")
	public void log3() {
		System.out.println("-----log3：" + Thread.currentThread().getName());
	}

}
